package edu.javeriana.aes.psw.context;

import edu.javeriana.aes.psw.forwarder.Forwarder;
import edu.javeriana.aes.psw.forwarder.TCPForwarder;
import edu.javeriana.aes.psw.forwarder.UDPForwarder;
import edu.javeriana.aes.psw.mensaje.Mensaje;
import edu.javeriana.aes.psw.mensaje.MensajeBean;
import edu.javeriana.aes.psw.receiver.Receiver;
import edu.javeriana.aes.psw.receiver.TCPReceiver;
import edu.javeriana.aes.psw.receiver.UDPReceiver;
import edu.javeriana.aes.psw.util.NetworkUtil;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class ContextCommunicationControllerBean
        implements ContextCommunicationController, ControllerListener {

    private Map<String, String> ipTables = new HashMap<String, String>();
    private Map<String, Mensaje> mensajes = new HashMap<String, Mensaje>();
    private Forwarder forwarderTCP;
    private Forwarder forwarderUDP;
    private Receiver receiverTCP;
    private Receiver receiverUDP;
    private String ip;
    private String hostname;

    // <editor-fold defaultstate="collapsed" desc="Constructor">
    public ContextCommunicationControllerBean() {
        try {
            ip = NetworkUtil.obtenerIP();
            hostname = NetworkUtil.obtenerNombre();

            forwarderTCP = new TCPForwarder();
            forwarderUDP = new UDPForwarder();
            receiverTCP = new TCPReceiver(this);
            receiverUDP = new UDPReceiver(this);

            inicializarTCPListener();
            inicializarUPDListener();
        } catch (IOException ex) {
            System.err.println(ex);
            System.exit(-1);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="init listeners">
    private void inicializarTCPListener() {
        Thread tcpListener = new Thread(new Runnable() {

            @Override
            public void run() {
                receiverTCP.recibir();
            }
        });
        tcpListener.start();
    }

    private void inicializarUPDListener() {
        Thread udpListener = new Thread(new Runnable() {

            @Override
            public void run() {
                receiverUDP.recibir();
            }
        });
        udpListener.start();
    }
    // </editor-fold>

    @Override
    public void saludar() {
        try {
            Mensaje mensaje =
                    new MensajeBean(ip, hostname, 0, new Date().getTime(), 0);
            forwarderUDP.enviar(mensaje);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    @Override
    public void enviarMensaje(Mensaje mensaje) {
        try {
            Set<String> ipSet = ipTables.keySet();

            for (String ip : ipSet) {
                Mensaje mensajeEnviar = new MensajeBean(
                        ip,
                        hostname,
                        mensaje.getTemperatura(),
                        new Date().getTime(),
                        mensaje.getFrecuencia());
                forwarderTCP.enviar(mensajeEnviar);
            }
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    @Override
    public Map<String, Mensaje> recibirMensajes() {
        Map<String, Mensaje> mapRetorno = new HashMap<String, Mensaje>();
        mapRetorno.putAll(mensajes);
        mensajes.clear();
        return mapRetorno;
    }

    @Override
    public void finalizar() {
        receiverTCP.finalizar();
        receiverUDP.finalizar();
    }

    // <editor-fold defaultstate="collapsed" desc="ControllerListener">
    @Override
    public void notificarMensajeTCP(Mensaje mensaje) {
        mensajes.put(mensaje.getIp(), mensaje);
    }

    @Override
    public void notificarMensajeUDP(Mensaje mensaje) {
        ipTables.put(mensaje.getIp(), mensaje.getAlias());
    }
    // </editor-fold>
}
